<!DOCTYPE html>
<html lang="en">

	<head>
		<meta charset="UTF-8">
		<title></title>
		<script src="../../js/lib/jquery-v3.0.0/jquery.js" type="text/javascript" charset="utf-8"></script>
		<style>
			.edit-box {
				height: 100px;
				width: 300px;
				border: 1px solid #d0d4d9;
				border-radius: 2px;
				outline: none;
				color: green;
				overflow: auto;
			}
			
			.face-list {
				margin-top: 10px;
				border-top: 1px dotted dodgerblue;
				border-bottom: 1px dotted dodgerblue;
				width: 300px;
			}
		</style>
	</head>

	<body>
		<div id="edit-box" class="edit-box" contenteditable="true"></div>
		<div class="face-list" id="face-list">
			<img src="../../img/qq-faces/1.gif" />
			<img src="../../img/qq-faces/2.gif" />
			<img src="../../img/qq-faces/3.gif" />
			<img src="../../img/qq-faces/4.gif" />
			<img src="../../img/qq-faces/5.gif" />
			<span>点击表情添加图标</span>
		</div>

		<textarea cols="40">这里是用于测试的填充内容</textarea>
		<script>
			var lastEditRange = null; // 定义最后光标对象
			var selection = null;
			var $editBox = $("#edit-box");
			var $faceList = $("#face-list");

			function setRange() {
				selection = window.getSelection(); // 获取选定对象
				lastEditRange = selection.getRangeAt(0);
			}
			// 编辑框点击事件
			// 编辑框按键弹起事件
			$editBox.on("click keyup", setRange)

			// 表情点击事件
			$faceList.on("click", "img", function(event) {
				debugger;
				$editBox.focus();
				// 获取选定对象
				var selection = getSelection()
				// 判断是否有最后光标对象存在
				if(lastEditRange) {
					// 存在最后光标对象，选定对象清除所有光标并添加最后光标还原之前的状态
					selection.removeAllRanges()
					selection.addRange(lastEditRange)
				}
				// 如果是编辑框范围。则插入表情
				var img = new Image();
				img.src = $(event.currentTarget).attr("src");

				// 判断选定对象范围是编辑框还是文本节点
				if(selection.anchorNode.nodeName != '#text') {
					var editBox = $editBox.get(0);
					var len = editBox.childNodes.length;
					if(len > 0) {
						// 如果文本框的子元素大于0，则表示有其他元素，则按照位置插入表情节点
						for(var i = 0; i < len; i++) {
							if(i == selection.anchorOffset) {
								editBox.insertBefore(img, editBox.childNodes[i]);
							}
						}
					} else {
						// 否则直接插入一个表情元素
						$editBox.append(img);
					}
					// 创建新的光标对象
					var range = document.createRange();
					// 光标对象的范围界定为新建的表情节点
					range.selectNodeContents(img);
					// 光标位置定位在表情节点的最大长度
					range.setStart(img, img.length);
					// 使光标开始和光标结束重叠
					range.collapse(true);
					// 清除选定对象的所有光标对象
					selection.removeAllRanges();
					// 插入新的光标对象
					selection.addRange(range);
				} else {
					// 如果是文本节点则先获取光标对象
					var range = selection.getRangeAt(0);
					// 获取光标对象的范围界定对象，一般就是textNode对象
					var textNode = range.startContainer;
					// 获取光标位置
					var rangeStartOffset = range.startOffset;
					// 文本节点在光标位置处插入新的表情内容
					textNode.insertData(rangeStartOffset, img)
					// 光标移动到到原来的位置加上新内容的长度
					range.setStart(textNode, rangeStartOffset + img)
					// 光标开始和光标结束重叠
					range.collapse(true)
					// 清除选定对象的所有光标对象
					selection.removeAllRanges()
					// 插入新的光标对象
					selection.addRange(range)
				}
				// 无论如何都要记录最后光标对象
				lastEditRange = selection.getRangeAt(0)
			})
		</script>
	</body>

</html>